﻿#ifndef AAHEADCONFIG_H
#define AAHEADCONFIG_H

#include "GTMotion/gtdispenser.h"
#include "configManager/configobject.h"
#include "configManager/configobjectarray.h"

class GlueCheckParam : public ConfigObject
{
    Q_OBJECT

    Q_PROPERTY(double resoultion READ resoultion WRITE setResoultion NOTIFY resoultionChanged)
    Q_PROPERTY(double maxGlueWidth READ maxGlueWidth WRITE setMaxGlueWidth NOTIFY maxGlueWidthChanged)
    Q_PROPERTY(double minGlueWidth READ minGlueWidth WRITE setMinGlueWidth NOTIFY minGlueWidthChanged)
    Q_PROPERTY(double aveGlueWidthUpperLimit READ aveGlueWidthUpperLimit WRITE setAveGlueWidthUpperLimit NOTIFY
                   aveGlueWidthUpperLimitChanged)
    Q_PROPERTY(double aveGlueWidthLowerLimit READ aveGlueWidthLowerLimit WRITE setAveGlueWidthLowerLimit NOTIFY
                   aveGlueWidthLowerLimitChanged)

public:
    GlueCheckParam(QObject *parent = nullptr) : ConfigObject(parent)
    {
        init();
    }

    double resoultion() const
    {
        return m_resoultion;
    }

    double maxGlueWidth() const
    {
        return m_maxGlueWidth;
    }

    double minGlueWidth() const
    {
        return m_minGlueWidth;
    }

    double aveGlueWidthUpperLimit() const
    {
        return m_aveGlueWidthUpperLimit;
    }

    double aveGlueWidthLowerLimit() const
    {
        return m_aveGlueWidthLowerLimit;
    }

public slots:
    void setResoultion(double resoultion)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_resoultion, resoultion))
            return;

        m_resoultion = resoultion;
        emit resoultionChanged(m_resoultion);
    }

    void setMaxGlueWidth(double maxGlueWidth)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_maxGlueWidth, maxGlueWidth))
            return;

        m_maxGlueWidth = maxGlueWidth;
        emit maxGlueWidthChanged(m_maxGlueWidth);
    }

    void setMinGlueWidth(double minGlueWidth)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_minGlueWidth, minGlueWidth))
            return;

        m_minGlueWidth = minGlueWidth;
        emit minGlueWidthChanged(m_minGlueWidth);
    }

    void setAveGlueWidthUpperLimit(double aveGlueWidthUpperLimit)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_aveGlueWidthUpperLimit, aveGlueWidthUpperLimit))
            return;

        m_aveGlueWidthUpperLimit = aveGlueWidthUpperLimit;
        emit aveGlueWidthUpperLimitChanged(m_aveGlueWidthUpperLimit);
    }

    void setAveGlueWidthLowerLimit(double aveGlueWidthLowerLimit)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_aveGlueWidthLowerLimit, aveGlueWidthLowerLimit))
            return;

        m_aveGlueWidthLowerLimit = aveGlueWidthLowerLimit;
        emit aveGlueWidthLowerLimitChanged(m_aveGlueWidthLowerLimit);
    }

signals:
    void resoultionChanged(double resoultion);

    void maxGlueWidthChanged(double maxGlueWidth);

    void minGlueWidthChanged(double minGlueWidth);

    void aveGlueWidthUpperLimitChanged(double aveGlueWidthUpperLimit);

    void aveGlueWidthLowerLimitChanged(double aveGlueWidthLowerLimit);

private:
    double m_resoultion = 0;
    double m_maxGlueWidth = 0;
    double m_minGlueWidth = 0;
    double m_aveGlueWidthUpperLimit = 0;
    double m_aveGlueWidthLowerLimit = 0;
};

class AaHeadConfig : public ConfigObject
{
    Q_OBJECT
    Q_PROPERTY(int shotGlueDotTime READ shotGlueDotTime WRITE setShotGlueDotTime NOTIFY shotGlueDotTimeChanged)
    Q_PROPERTY(double shotterTopToCameraOffsetX READ shotterTopToCameraOffsetX WRITE setShotterTopToCameraOffsetX NOTIFY
                   shotterTopToCameraOffsetXChanged)
    Q_PROPERTY(double shotterTopToCameraOffsetY READ shotterTopToCameraOffsetY WRITE setShotterTopToCameraOffsetY NOTIFY
                   shotterTopToCameraOffsetYChanged)
    Q_PROPERTY(double shotterTopToCameraOffsetT READ shotterTopToCameraOffsetT WRITE setShotterTopToCameraOffsetT NOTIFY
                   shotterTopToCameraOffsetTChanged)

    Q_PROPERTY(double shotterSoftLandHeight READ shotterSoftLandHeight WRITE setShotterSoftLandHeight NOTIFY
                   shotterSoftLandHeightChanged)
    Q_PROPERTY(double shotGlueOffsetZ READ shotGlueOffsetZ WRITE setShotGlueOffsetZ NOTIFY shotGlueOffsetZChanged)

    Q_PROPERTY(double upLookCameraToDownLookCameraOffsetX READ upLookCameraToDownLookCameraOffsetX WRITE
                   setUpLookCameraToDownLookCameraOffsetX NOTIFY upLookCameraToDownLookCameraOffsetXChanged)
    Q_PROPERTY(double upLookCameraToDownLookCameraOffsetY READ upLookCameraToDownLookCameraOffsetY WRITE
                   setUpLookCameraToDownLookCameraOffsetY NOTIFY upLookCameraToDownLookCameraOffsetYChanged)
    Q_PROPERTY(double upLookCameraToDownLookCameraOffsetTheta READ upLookCameraToDownLookCameraOffsetTheta WRITE
                   setUpLookCameraToDownLookCameraOffsetTheta NOTIFY upLookCameraToDownLookCameraOffsetThetaChanged)
    Q_PROPERTY(bool useXYOffset READ useXYOffset WRITE setUseXYOffset NOTIFY useXYOffsetChanged)
    Q_PROPERTY(bool useThetaOffset READ useThetaOffset WRITE setUseThetaOffset NOTIFY useThetaOffsetChanged)

    Q_PROPERTY(double softLandVel READ softLandVel WRITE setSoftLandVel NOTIFY softLandVelChanged)
    Q_PROPERTY(double softLandForce READ softLandForce WRITE setSoftLandForce NOTIFY softLandForceChanged)

    Q_PROPERTY(int gripLensDelay READ gripLensDelay WRITE setGripLensDelay NOTIFY gripLensDelayChanged)

    Q_PROPERTY(
        int extendGripperDelay READ extendGripperDelay WRITE setExtendGripperDelay NOTIFY extendGripperDelayChanged)
    Q_PROPERTY(int assemblyDelay READ assemblyDelay WRITE setAssemblyDelay NOTIFY assemblyDelayChanged)

    Q_PROPERTY(bool doUVing READ doUVing WRITE setDoUVing NOTIFY doUVingChanged)
    Q_PROPERTY(int actionUVTime READ actionUVTime WRITE setActionUVTime NOTIFY actionUVTimeChanged)
    Q_PROPERTY(int closeUVTime READ closeUVTime WRITE setCloseUVTime NOTIFY closeUVTimeChanged)

    Q_PROPERTY(int setVacuumDelay READ setVacuumDelay WRITE setSetVacuumDelay NOTIFY setVacuumDelayChanged)
    Q_PROPERTY(QString dispenseParthFileName READ dispenseParthFileName WRITE setDispenseParthFileName NOTIFY
                   dispenseParthFileNameChanged)

    Q_PROPERTY(GlueCheckParam *glueCheckParam READ glueCheckParam)
    Q_PROPERTY(DispenserConfig *dispenserConfig READ dispenserConfig)

    Q_PROPERTY(bool isDryRun READ isDryRun WRITE setIsDryRun NOTIFY isDryRunChanged)

public:
    AaHeadConfig(QObject *parent = nullptr) : ConfigObject(parent)
    {
        m_glueCheckParam = new GlueCheckParam(this);
        m_dispenserConfig = new DispenserConfig(this);
        init();
    }

    int shotGlueDotTime() const
    {
        return m_shotGlueDotTime;
    }

    double shotterTopToCameraOffsetX() const
    {
        return m_shotterTopToCameraOffsetX;
    }

    double shotterTopToCameraOffsetY() const
    {
        return m_shotterTopToCameraOffsetY;
    }

    double shotterSoftLandHeight() const
    {
        return m_shotterSoftLandHeight;
    }

    double shotGlueOffsetZ() const
    {
        return m_shotGlueOffset;
    }

    double upLookCameraToDownLookCameraOffsetX() const
    {
        return m_upLookCameraToDownLookCameraOffsetX;
    }

    double upLookCameraToDownLookCameraOffsetY() const
    {
        return m_upLookCameraToDownLookCameraOffsetY;
    }

    double upLookCameraToDownLookCameraOffsetTheta() const
    {
        return m_upLookCameraToDownLookCameraOffsetTheta;
    }

    double softLandVel() const
    {
        return m_softLandVel;
    }

    double softLandForce() const
    {
        return m_softLandForce;
    }

    int gripLensDelay() const
    {
        return m_gripLensDelay;
    }

    int assemblyDelay() const
    {
        return m_assemblyDelay;
    }

    bool doUVing() const
    {
        return m_doUVing;
    }

    int actionUVTime() const
    {
        return m_actionUVTime;
    }

    int closeUVTime() const
    {
        return m_closeUVTime;
    }

    int extendGripperDelay() const
    {
        return m_extendGripperDelay;
    }

    int setVacuumDelay() const
    {
        return m_setVacuumDelay;
    }

    QString dispenseParthFileName() const
    {
        return m_dispenseParthFileName;
    }

    double shotterTopToCameraOffsetT() const
    {
        return m_shotterTopToCameraOffsetT;
    }

    GlueCheckParam *glueCheckParam() const
    {
        return m_glueCheckParam;
    }

    DispenserConfig *dispenserConfig() const
    {
        return m_dispenserConfig;
    }

    bool isDryRun() const
    {
        return m_isDryRun;
    }

    bool useXYOffset() const
    {
        return m_useXYOffset;
    }

    bool useThetaOffset() const
    {
        return m_useThetaOffset;
    }

public slots:
    void setShotGlueDotTime(int shotGlueDotTime)
    {
        if (m_shotGlueDotTime == shotGlueDotTime)
            return;

        m_shotGlueDotTime = shotGlueDotTime;
        emit shotGlueDotTimeChanged(m_shotGlueDotTime);
    }

    void setShotterTopToCameraOffsetX(double shotterTopToCameraOffsetX)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_shotterTopToCameraOffsetX, shotterTopToCameraOffsetX))
            return;

        m_shotterTopToCameraOffsetX = shotterTopToCameraOffsetX;
        emit shotterTopToCameraOffsetXChanged(m_shotterTopToCameraOffsetX);
    }

    void setShotterTopToCameraOffsetY(double shotterTopToCameraOffsetY)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_shotterTopToCameraOffsetY, shotterTopToCameraOffsetY))
            return;

        m_shotterTopToCameraOffsetY = shotterTopToCameraOffsetY;
        emit shotterTopToCameraOffsetYChanged(m_shotterTopToCameraOffsetY);
    }

    void setShotterSoftLandHeight(double shotterSoftLandHeight)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_shotterSoftLandHeight, shotterSoftLandHeight))
            return;

        m_shotterSoftLandHeight = shotterSoftLandHeight;
        emit shotterSoftLandHeightChanged(m_shotterSoftLandHeight);
    }

    void setShotGlueOffsetZ(double shotGlueOffset)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_shotGlueOffset, shotGlueOffset))
            return;

        m_shotGlueOffset = shotGlueOffset;
        emit shotGlueOffsetZChanged(m_shotGlueOffset);
    }

    void setUpLookCameraToDownLookCameraOffsetX(double upLookCameraToDownLookCameraOffsetX)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_upLookCameraToDownLookCameraOffsetX, upLookCameraToDownLookCameraOffsetX))
            return;

        m_upLookCameraToDownLookCameraOffsetX = upLookCameraToDownLookCameraOffsetX;
        emit upLookCameraToDownLookCameraOffsetXChanged(m_upLookCameraToDownLookCameraOffsetX);
    }

    void setUpLookCameraToDownLookCameraOffsetY(double upLookCameraToDownLookCameraOffsetY)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_upLookCameraToDownLookCameraOffsetY, upLookCameraToDownLookCameraOffsetY))
            return;

        m_upLookCameraToDownLookCameraOffsetY = upLookCameraToDownLookCameraOffsetY;
        emit upLookCameraToDownLookCameraOffsetYChanged(m_upLookCameraToDownLookCameraOffsetY);
    }

    void setUpLookCameraToDownLookCameraOffsetTheta(double upLookCameraToDownLookCameraOffsetTheta)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_upLookCameraToDownLookCameraOffsetTheta, upLookCameraToDownLookCameraOffsetTheta))
            return;

        m_upLookCameraToDownLookCameraOffsetTheta = upLookCameraToDownLookCameraOffsetTheta;
        emit upLookCameraToDownLookCameraOffsetThetaChanged(m_upLookCameraToDownLookCameraOffsetTheta);
    }

    void setSoftLandVel(double softLandVel)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_softLandVel, softLandVel))
            return;

        m_softLandVel = softLandVel;
        emit softLandVelChanged(m_softLandVel);
    }

    void setSoftLandForce(double softLandForce)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_softLandForce, softLandForce))
            return;

        m_softLandForce = softLandForce;
        emit softLandForceChanged(m_softLandForce);
    }

    void setGripLensDelay(int gripLensDelay)
    {
        if (m_gripLensDelay == gripLensDelay)
            return;

        m_gripLensDelay = gripLensDelay;
        emit gripLensDelayChanged(m_gripLensDelay);
    }

    void setAssemblyDelay(int assemblyDelay)
    {
        if (m_assemblyDelay == assemblyDelay)
            return;

        m_assemblyDelay = assemblyDelay;
        emit assemblyDelayChanged(m_assemblyDelay);
    }

    void setDoUVing(bool doUVing)
    {
        if (m_doUVing == doUVing)
            return;

        m_doUVing = doUVing;
        emit doUVingChanged(m_doUVing);
    }

    void setActionUVTime(int actionUVTime)
    {
        if (m_actionUVTime == actionUVTime)
            return;

        m_actionUVTime = actionUVTime;
        emit actionUVTimeChanged(m_actionUVTime);
    }

    void setCloseUVTime(int closeUVTime)
    {
        if (m_closeUVTime == closeUVTime)
            return;

        m_closeUVTime = closeUVTime;
        emit closeUVTimeChanged(m_closeUVTime);
    }

    void setExtendGripperDelay(int extendGripperDelay)
    {
        if (m_extendGripperDelay == extendGripperDelay)
            return;

        m_extendGripperDelay = extendGripperDelay;
        emit extendGripperDelayChanged(m_extendGripperDelay);
    }

    void setSetVacuumDelay(int setVacuumDelay)
    {
        if (m_setVacuumDelay == setVacuumDelay)
            return;

        m_setVacuumDelay = setVacuumDelay;
        emit setVacuumDelayChanged(m_setVacuumDelay);
    }

    void setDispenseParthFileName(QString dispenseParthFileName)
    {
        if (m_dispenseParthFileName == dispenseParthFileName)
            return;

        m_dispenseParthFileName = dispenseParthFileName;
        emit dispenseParthFileNameChanged(m_dispenseParthFileName);
    }

    void setShotterTopToCameraOffsetT(double shotterTopToCameraOffsetT)
    {
        // qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_shotterTopToCameraOffsetT, shotterTopToCameraOffsetT))
            return;

        m_shotterTopToCameraOffsetT = shotterTopToCameraOffsetT;
        emit shotterTopToCameraOffsetTChanged(m_shotterTopToCameraOffsetT);
    }

    void setIsDryRun(bool isDryRun)
    {
        if (m_isDryRun == isDryRun)
            return;

        m_isDryRun = isDryRun;
        emit isDryRunChanged(m_isDryRun);
    }

    void setUseXYOffset(bool useXYOffset)
    {
        if (m_useXYOffset == useXYOffset)
            return;

        m_useXYOffset = useXYOffset;
        emit useXYOffsetChanged(m_useXYOffset);
    }

    void setUseThetaOffset(bool useThetaOffset)
    {
        if (m_useThetaOffset == useThetaOffset)
            return;

        m_useThetaOffset = useThetaOffset;
        emit useThetaOffsetChanged(m_useThetaOffset);
    }

signals:
    void shotGlueDotTimeChanged(int shotGlueDotTime);

    void shotterTopToCameraOffsetXChanged(double shotterTopToCameraOffsetX);

    void shotterTopToCameraOffsetYChanged(double shotterTopToCameraOffsetY);

    void shotterSoftLandHeightChanged(double shotterSoftLandHeight);

    void shotGlueOffsetZChanged(double shotGlueOffsetZ);

    void upLookCameraToDownLookCameraOffsetXChanged(double upLookCameraToDownLookCameraOffsetX);

    void upLookCameraToDownLookCameraOffsetYChanged(double upLookCameraToDownLookCameraOffsetY);

    void upLookCameraToDownLookCameraOffsetThetaChanged(double upLookCameraToDownLookCameraOffsetTheta);

    void softLandVelChanged(double softLandVel);

    void softLandForceChanged(double softLandForce);

    void gripLensDelayChanged(int gripLensDelay);

    void assemblyDelayChanged(int assemblyDelay);

    void doUVingChanged(bool doUVing);

    void actionUVTimeChanged(int actionUVTime);

    void closeUVTimeChanged(int closeUVTime);

    void extendGripperDelayChanged(int extendGripperDelay);

    void setVacuumDelayChanged(int setVacuumDelay);

    void dispenseParthFileNameChanged(QString dispenseParthFileName);

    void shotterTopToCameraOffsetTChanged(double shotterTopToCameraOffsetT);

    void isDryRunChanged(bool isDryRun);

    void useXYOffsetChanged(bool useXYOffset);

    void useThetaOffsetChanged(bool useThetaOffset);

private:
    int m_shotGlueDotTime = 500;
    double m_shotterTopToCameraOffsetX = 0;
    double m_shotterTopToCameraOffsetY = 0;
    double m_shotterSoftLandHeight = 0;
    double m_shotGlueOffset = 0;

    double m_upLookCameraToDownLookCameraOffsetX = 0;
    double m_upLookCameraToDownLookCameraOffsetY = 0;
    double m_upLookCameraToDownLookCameraOffsetTheta = 0;
    double m_softLandVel = 0;
    double m_softLandForce = 0;
    int m_gripLensDelay = 0;
    int m_assemblyDelay = 0;
    bool m_doUVing = false;

    int m_actionUVTime = 500;
    int m_closeUVTime = 500;
    int m_extendGripperDelay = 200;
    int m_setVacuumDelay = 200;

    QString m_dispenseParthFileName = "";
    double m_shotterTopToCameraOffsetT = 0;
    GlueCheckParam *m_glueCheckParam;
    DispenserConfig *m_dispenserConfig;
    bool m_isDryRun = false;
    bool m_useXYOffset = false;
    bool m_useThetaOffset = false;

};

#endif    // AaHeadCONFIG_H
